home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * Source Control
- * --------------
- * $Header: algorithm.c,v 35.11 88/04/22 15:17:07 bart Exp $
- *
- * by Bart Whitebook
- *
- * Copyright (c) 1988 Commodore-Amiga, Inc.
- *
- * Executables based on this information may be used in software
- * for Commodore Amiga computers. All other rights reserved.
- *
- * This information is provided "as is"; no warranties are made.
- * All use is at your own risk, and no liability or responsibility is assumed.
- *
- ******************************************************************************/
-
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/gfx.h>
- #include <graphics/rastport.h>
-
- /* scale_rastport.c -- scale a portion of one rastport to fit into another */
-
- dispose_temprp(temprp)
- struct RastPort *temprp;
- {
- if(temprp)
- {
- struct BitMap *tempbm = temprp->BitMap;
-
- if(tempbm)
- {
- int numbytes = (tempbm->Depth * tempbm->BytesPerRow);
-
- if((numbytes)&&(tempbm->Planes[0]))
- {
- FreeMem(tempbm->Planes[0],numbytes);
- }
- FreeMem(tempbm,sizeof(*tempbm));
- }
- FreeMem(temprp,sizeof(*temprp));
- }
- }
-
- struct RastPort *get_temprp(srcrp)
- struct RastPort *srcrp;
- {
- struct RastPort *temprp = NULL;
-
- if(srcrp)
- {
- /* allocate temprp */
-
- if ((temprp = (struct RastPort *)
- AllocMem(sizeof(*temprp),MEMF_PUBLIC)) != NULL)
- {
- struct BitMap *tempbm;
- UBYTE *mem;
-
- /* copy srcrp */
-
- *temprp = *srcrp;
-
- /* null layer pointer */
-
- temprp->Layer = NULL;
-
- /* allocate tempbm */
-
- if ((tempbm = (struct BitMap *)
- AllocMem(sizeof(*tempbm),MEMF_PUBLIC)) == NULL)
- {
- FreeMem(temprp,sizeof(*temprp));
- temprp = NULL;
- }
- else
- {
- int width;
- int bytesperrow;
- int numbytes;
-
- /* copy srcrp bitmap */
-
- *tempbm = *(srcrp->BitMap);
-
- /* force copy of bitmap to one line high */
-
- tempbm->Rows = 1;
-
- /* allocate temp memory for one line high bitmap */
-
- width = srcrp->BitMap->BytesPerRow << 3;
-
- if(width < 1)
- {
- FreeMem(tempbm,sizeof(*tempbm));
- FreeMem(temprp,sizeof(*temprp));
- temprp = NULL;
- }
- else
- {
- bytesperrow = (((width+0xf)>>4)<<1);
-
- tempbm->BytesPerRow = bytesperrow;
-
- numbytes = (tempbm->Depth * bytesperrow);
-
- if ((mem = (UBYTE *)
- AllocMem(numbytes,MEMF_CHIP)) == NULL)
- {
- FreeMem(tempbm,sizeof(*tempbm));
- FreeMem(temprp,sizeof(*temprp));
- temprp = NULL;
- }
- else
- {
- int i;
-
- /* initialize plane pointers for temp bitmap */
-
- for(i=0; i<tempbm->Depth; i++)
- {
- tempbm->Planes[i] = mem+(tempbm->BytesPerRow * i);
- }
-
- /* link tempbm to temprp */
-
- temprp->BitMap = tempbm;
-
- /* exit */
- }
- }
- }
- }
- }
- return(temprp);
- }
-
- scale_rastport(srcrp,srcr,dstrp,dstr)
- struct RastPort *srcrp;
- struct Rectangle *srcr;
- struct RastPort *dstrp;
- struct Rectangle *dstr;
- {
- LONG error = FALSE;
-
- /* origin of source rectangle */
-
- WORD x = srcr->MinX;
- WORD y = srcr->MinY;
- WORD X = dstr->MinX;
- WORD Y = dstr->MinY;
-
- /* scale from m x n src rectangle to M x N dst rectangle */
-
- WORD m = (srcr->MaxX - x) + 1;
- WORD n = (srcr->MaxY - y) + 1;
- WORD M = (dstr->MaxX - X) + 1;
- WORD N = (dstr->MaxY - Y) + 1;
-
- /* map pixels from source to destination bitmap */
-
- LONG I = 0;
- LONG J = 0;
-
- LONG II = 0;
- LONG JJ = 0;
-
- /* readpixelarray */
-
- struct RastPort *temprp = get_temprp(srcrp);
-
- if(temprp)
- {
- UWORD *array = (UWORD *) AllocMem((m*2),MEMF_PUBLIC|MEMF_CLEAR);
- WORD n_err_N = 0;
-
- if(array)
- {
- WORD rectflag = FALSE;
- WORD M_div_m = 0;
- WORD N_div_n = 0;
- WORD m_mod_M;
- WORD n_mod_N;
- WORD m_neg_M;
- WORD n_neg_N;
- LONG iii;
- LONG jjj;
- LONG ii;
- LONG jj;
-
- /* initialize static variables */
-
- /* M_div_m = M/m; */
- /* N_div_n = N/n; */
-
- m_mod_M = m%M;
- n_mod_N = n%N;
-
- /* increments to write by */
-
- iii = (M_div_m < 1) ? 1: M_div_m;
- jjj = (N_div_n < 1) ? 1: N_div_n;
-
- /* write pixels or rectangles? */
-
- if((iii>1)||(jjj>1)) rectflag = TRUE;
-
- /* scaling variables */
-
- m_neg_M = (m_mod_M-m) * iii;
-
- n_neg_N = (n_mod_N-n) * jjj;
-
- /* for all pixels in the destination rectangle */
-
- kprintf("scale_rastport: M == %ld, N == %ld\n",M,N);
-
- for(J=0; J<N; J+=jjj)
- {
- WORD m_err_M = 0;
-
- /* map line to destination */
-
- II = 0;
-
- jj = JJ/N;
-
- /* determine first most popular j */
- {
- WORD n_ERR_N = (n_err_N)%N;
- LONG j = jj;
- WORD n_last_N = -n_ERR_N;
- WORD n_next_N = N;
-
- n_ERR_N += n;
-
- /* until next dest pixel */
-
- n_ERR_N -= N;
-
- while(!(n_ERR_N < 0))
- {
- if(n_next_N > n_last_N)
- {
- n_last_N = n_next_N;
- j++;
- }
- n_ERR_N -= N;
- }
- n_next_N += n_ERR_N;
-
- if(n_next_N > n_last_N)
- {
- n_last_N = n_next_N;
- j++;
- }
-
- ReadPixelLine(srcrp,x,y+j,m,array,NULL,temprp);
- }
-
-
- for(I=0; I<M; I+=iii)
- {
-
- ii = II/M;
-
- /* map pixel to destination */
- {
- /* determine first most popular i */
-
- WORD m_ERR_M = (m_err_M)%M;
- LONG i = ii;
- WORD m_last_M = -m_ERR_M;
- WORD m_next_M = M;
-
- m_ERR_M += m;
-
- /* until next dest pixel */
-
- m_ERR_M -= M;
-
- while(!(m_ERR_M < 0))
- {
- if(m_next_M > m_last_M)
- {
- m_last_M = m_next_M;
- i++;
- }
- m_ERR_M -= M;
- }
- m_next_M += m_ERR_M;
-
- if(m_next_M > m_last_M)
- {
- m_last_M = m_next_M;
- i++;
- }
-
- /* map pixel */
-
- SetAPen(dstrp,*(array+i));
-
- if(rectflag)
- {
- RectFill(dstrp,X+I,Y+J,X+I+iii-1,Y+J+jjj-1);
- }
- else
- {
- WritePixel(dstrp,X+I,Y+J);
- }
-
- }
-
- m_err_M += m_neg_M;
-
- II += m * iii;
-
- if(error) break;
- }
-
- n_err_N += n_neg_N;
-
- JJ += n * jjj;
-
- if(error) break;
- }
-
- FreeMem(array,(m*2));
- }
- else
- {
- error = TRUE;
- }
-
- dispose_temprp(temprp);
- }
- else
- {
- error = TRUE;
- }
-
- return(error);
- }
-